package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.template.AipFaceTemplate;
import com.tanhua.commons.template.HuanXinTemplate;
import com.tanhua.commons.template.OssTemplate;
import com.tanhua.commons.template.SmsTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.vo.ErrorResult;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liuyp
 * @date 2021/01/24
 */
@Slf4j
@Service
public class UserService {
    @Reference
    private UserApi userApi;
    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Value("${tanhua.secret}")
    private String secret;

    public ResponseEntity sendSms(String mobile) {
        //1. 发送手机短信验证码
        // String code = smsTemplate.sendSms(mobile);
        String code = "123456";

        //2. 把验证码存储到Redis里，设置有效期5分钟
        redisTemplate.opsForValue().set("CODE_" + mobile, code, Duration.ofMinutes(5));

        //3. 返回结果
        return ResponseEntity.ok(null);
    }

    public ResponseEntity loginVerification(String mobile, String code) {
        //1. 校验验证码是否正确
        String value = redisTemplate.opsForValue().get("CODE_" + mobile);
        if (value == null || !value.equals(code)) {
            return ResponseEntity.status(500).body(ErrorResult.smsInvalid());
        }
        redisTemplate.delete("CODE_" + mobile);

        //2. 根据手机号查询用户对象
        User user = userApi.findByMobile(mobile);
        boolean isNew = false;
        if (user == null) {
            //说明是第一次登录，我们要把个手机号，注册到用户表里
            user = new User();
            user.setMobile(mobile);
            user.setPassword(DigestUtils.md5Hex("123456"));
            // user.setCreated(new Date());
            // user.setUpdated(new Date());

            //保存到数据库
            long userId = userApi.save(user);
            user.setId(userId);

            //同时把用户注册到环信，提供当前用户的环信id和密码
            huanXinTemplate.register(String.valueOf(userId), "123456");
            isNew = true;
        }
        //使用RocketMQ推送消息，记录日志
        HashMap<String, Object> message = new HashMap<>();
        message.put("userId",user.getId());
        message.put("type",isNew?"0102":"0101");
        message.put("date",new DateTime().toString("yyyy-MM-dd"));
        rocketMQTemplate.convertAndSend("tanhua-log",message);
        log.info("发送操作日志信息,topic：{},消息内容：{}","tanhua-log",message);

        //3. 生成token
        String token = JwtUtils.createToken(mobile, user.getId(), secret);

        //4. 以token为key，把User数据存储到redis里
        String userJson = JSON.toJSONString(user);
        redisTemplate.opsForValue().set("TOKEN_" + token, userJson, Duration.ofHours(1));

        //5. 准备返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("isNew", isNew);
        result.put("token", token);
        return ResponseEntity.ok(result);
    }

    public ResponseEntity saveUserInfo(UserInfo userInfo) {
        //1. 根据token找到当前用户：从当前线程上获取，使用UserHolder
        User user = UserHolder.getUser();

        //2. 给userInfo补全数据：id
        userInfo.setId(user.getId());

        //3. 调用api，保存到数据库
        userInfoApi.save(userInfo);

        return ResponseEntity.ok(null);
    }

    public ResponseEntity saveAvatar(MultipartFile headPhoto) throws IOException {
        //1. 根据token找到对应的用户
        User user = UserHolder.getUser();

        //2. 人脸检测
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (!detect) {
            return ResponseEntity.status(500).body(ErrorResult.faceDetectFailed());
        }

        //3. 上传到阿里云OSS
        String path = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //4. 更新到数据库
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(path);
        userInfoApi.update(userInfo);

        return ResponseEntity.ok(null);
    }
}
